{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# 二、预备知识\n",
    "\n",
    "## 2.1 数据操作\n",
    "\n",
    "### 2.1.1 创建张量\n",
    "\n",
    "- n维数组，也称为张量(tensor)。\n",
    "- 一维数组，称为向量(vector)\n",
    "- 二维数组称为矩阵(matrix)\n",
    "- 在深度学习框架中，统称为张量\n",
    "\n",
    "除了NumPy的ndarray表示n维数组，深度学习框架中也有内置的张量(n维数组)，这些深度学习框架的张量和NumPy的n维数组类似，用法也类似。"
   ],
   "id": "ca8fd413c5b63cca"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T13:57:03.729039Z",
     "start_time": "2025-11-14T13:57:02.876768Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import torch # 导入pytorch\n",
    "x = torch.arange(12) # 创建一个行向量\n",
    "x.shape # 向量的形状，行向量的形状和大小数值相同\n",
    "x.numel() # 向量的大小\n",
    "X = x.reshape(3, 4) # 改变行向量的形状，1*12 -> 3*4，从向量变为矩阵\n",
    "# 通过reshape修改行向量的形状时，没必要手动计算，可以使用-1代替一个参数\n",
    "# X = x.reshape(3, -1)\n",
    "# X = x.reshape(-1, 4)\n",
    "X"
   ],
   "id": "6da6c412dd966288",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0,  1,  2,  3],\n",
       "        [ 4,  5,  6,  7],\n",
       "        [ 8,  9, 10, 11]])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-12T14:56:13.085131Z",
     "start_time": "2025-11-12T14:56:13.069301Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 创建元素全是0的张量\n",
    "torch.zeros((2, 3, 4))\n",
    "# 创建元素全是1的张量\n",
    "torch.ones((2, 3, 4))\n",
    "# 创建元素服从标准正态分布的随机值的张量\n",
    "torch.randn((2, 3, 4))\n",
    "# 通过python嵌套列表创建张量\n",
    "torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])"
   ],
   "id": "a9782b1499c522ea",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[2, 1, 4, 3],\n",
       "        [1, 2, 3, 4],\n",
       "        [4, 3, 2, 1]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 15
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 2.1.2 向量运算\n",
    "\n",
    "加减乘除运算就是各个元素分别进行加减乘除，进行算术运算的两个张量要形状相同，还可以进行幂运算"
   ],
   "id": "58c53105164cf218"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-12T15:09:36.107605Z",
     "start_time": "2025-11-12T15:09:36.051654Z"
    }
   },
   "cell_type": "code",
   "source": [
    "x = torch.tensor([1.0, 2, 4, 8])\n",
    "y = torch.tensor([2, 2, 2, 2])\n",
    "# 加减乘除算数运算\n",
    "x + y, x - y, x * y, x / y, x ** y  # **运算符是求幂运算"
   ],
   "id": "1f04911644a08eea",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([ 3.,  4.,  6., 10.]),\n",
       " tensor([-1.,  0.,  2.,  6.]),\n",
       " tensor([ 2.,  4.,  8., 16.]),\n",
       " tensor([0.5000, 1.0000, 2.0000, 4.0000]),\n",
       " tensor([ 1.,  4., 16., 64.]))"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 16
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-12T15:10:54.326078Z",
     "start_time": "2025-11-12T15:10:54.301647Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# e的幂\n",
    "torch.exp(x)"
   ],
   "id": "cff80a63a4bc34c1",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 17
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T13:57:42.824657Z",
     "start_time": "2025-11-14T13:57:42.809422Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 张量连接\n",
    "X = torch.arange(12, dtype=torch.float32).reshape((3,4))\n",
    "# print(X)\n",
    "Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])\n",
    "# print(Y)\n",
    "# 通过o轴连接（形状第一个参数）# 通过1轴连接（形状第二个参数）\n",
    "torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)"
   ],
   "id": "537484e4a8ab6da0",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[ 0.,  1.,  2.,  3.],\n",
       "         [ 4.,  5.,  6.,  7.],\n",
       "         [ 8.,  9., 10., 11.],\n",
       "         [ 2.,  1.,  4.,  3.],\n",
       "         [ 1.,  2.,  3.,  4.],\n",
       "         [ 4.,  3.,  2.,  1.]]),\n",
       " tensor([[ 0.,  1.,  2.,  3.,  2.,  1.,  4.,  3.],\n",
       "         [ 4.,  5.,  6.,  7.,  1.,  2.,  3.,  4.],\n",
       "         [ 8.,  9., 10., 11.,  4.,  3.,  2.,  1.]]))"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T14:01:22.189325Z",
     "start_time": "2025-11-14T14:01:22.181325Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 逻辑运算\n",
    "X, Y, X == Y"
   ],
   "id": "3f13d3b95e49f115",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[ 0.,  1.,  2.,  3.],\n",
       "         [ 4.,  5.,  6.,  7.],\n",
       "         [ 8.,  9., 10., 11.]]),\n",
       " tensor([[2., 1., 4., 3.],\n",
       "         [1., 2., 3., 4.],\n",
       "         [4., 3., 2., 1.]]),\n",
       " tensor([[False,  True, False,  True],\n",
       "         [False, False, False, False],\n",
       "         [False, False, False, False]]))"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 6
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T14:01:54.161692Z",
     "start_time": "2025-11-14T14:01:54.145594Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 所有元素求和，类似于python列表求和\n",
    "X.sum()"
   ],
   "id": "979bbd8894d13b6c",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(66.)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 2.1.3 广播机制(broadcasting mechanism)\n",
    "\n",
    "前面的运算只适用于形状相同的张量。如果形状不同，会触发广播机制，将参与运算的张量转换为相同是形状进行运算"
   ],
   "id": "688d9fa0007e2b3"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T14:06:06.460270Z",
     "start_time": "2025-11-14T14:06:06.451049Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 列向量\n",
    "a = torch.arange(3).reshape((3, 1))\n",
    "# 行向量\n",
    "b = torch.arange(2).reshape((1, 2))\n",
    "a, b"
   ],
   "id": "fc91a82882df1000",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[0],\n",
       "         [1],\n",
       "         [2]]),\n",
       " tensor([[0, 1]]))"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 10
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T14:06:59.137330Z",
     "start_time": "2025-11-14T14:06:59.121448Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 触发广播机制，自动转换为形状相同的张量\n",
    "a + b"
   ],
   "id": "79d31efcdb2b08d8",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0, 1],\n",
       "        [1, 2],\n",
       "        [2, 3]])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "触发广播时，会自动复制已有元素，即，列向量a广播为：\n",
    "\n",
    "```text\n",
    "0 0\n",
    "1 1\n",
    "2 2\n",
    "```\n",
    "\n",
    "行向量b广播为：\n",
    "\n",
    "```text\n",
    "0 1\n",
    "0 1\n",
    "0 1\n",
    "```"
   ],
   "id": "79756b14bc3fc917"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 2.1.4 索引和切片\n",
    "\n",
    "类似于python列表。"
   ],
   "id": "54a92f3296ba82eb"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T14:11:38.342224Z",
     "start_time": "2025-11-14T14:11:38.327990Z"
    }
   },
   "cell_type": "code",
   "source": [
    "X = torch.arange(12).reshape((3, 4))\n",
    "X"
   ],
   "id": "daf46d55985abb11",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0,  1,  2,  3],\n",
       "        [ 4,  5,  6,  7],\n",
       "        [ 8,  9, 10, 11]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 15
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T14:12:38.223128Z",
     "start_time": "2025-11-14T14:12:38.217288Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 索引 切片\n",
    "X[-1], X[1:3]"
   ],
   "id": "41736929e657d40b",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([ 8,  9, 10, 11]),\n",
       " tensor([[ 4,  5,  6,  7],\n",
       "         [ 8,  9, 10, 11]]))"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 17
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T14:13:45.500492Z",
     "start_time": "2025-11-14T14:13:45.473616Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 不同于python列表\n",
    "# 张量可以使用多个索引直接访问元素\n",
    "X[1, 2] = 9\n",
    "X"
   ],
   "id": "a051b19977b45219",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0,  1,  2,  3],\n",
       "        [ 4,  5,  9,  7],\n",
       "        [ 8,  9, 10, 11]])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 18
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T14:14:50.473221Z",
     "start_time": "2025-11-14T14:14:50.457568Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 通过上面的方法，可以批量复制\n",
    "X[0:2, :] = 12\n",
    "X"
   ],
   "id": "ac50cc0db6bf40ae",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[12, 12, 12, 12],\n",
       "        [12, 12, 12, 12],\n",
       "        [ 8,  9, 10, 11]])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 19
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 2.1.5 节省内存\n",
    "\n",
    "张量类似于C语言的数组，内存连续。为了防止自动分配内存空间，一般使用`Z[:] = X + Y`或`X += Y` 接收计算结果，而不用 `Z = X + Y`（这种写法会分配新的内存空间，造成内存浪费）"
   ],
   "id": "96e8a706a38eaa38"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 2.1.6 转换为NumPy的张量和python数字常量",
   "id": "6fbc4e03cbb5c1ee"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T14:21:37.453126Z",
     "start_time": "2025-11-14T14:21:37.440566Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 和NumPy张量可以互相转换\n",
    "A = X.numpy()\n",
    "B = torch.tensor(A)\n",
    "type(A), type(B)"
   ],
   "id": "c18aec86f66463bd",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(numpy.ndarray, torch.Tensor)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 20
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-14T14:24:05.601081Z",
     "start_time": "2025-11-14T14:24:05.573803Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 转换为python数字\n",
    "a = torch.tensor([3.5])\n",
    "a, a.item(), float(a), int(a)"
   ],
   "id": "3089408eae573e23",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([3.5000]), 3.5, 3.5, 3)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 21
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
